--- 模块功能：MQTT客户端处理-科信自控
-- @author zfh
-- @module mqtt.mqttTask
-- @license MIT
-- @copyright zfh
-- @release 2023.06.05
module(..., package.seeall)

require "misc"
require "mqtt"
require "mqttInMsg"
require "mqttOutMsg"
require "nvm"
require "modbusrtu"
require "terminalSendTheme"

-- 初始化nvm获取配置参数
nvm.init("config.lua", true)
-- 参数初始化
local ready, mqttHost, mqttPort, mqttKeepAlive, mqttLoginName, mqttLoginPwm,
      mqttTransport, mqttConnectionTimeout, mqttCleanSession, mQTTVersion,
      mqttQos, mqttRetain, sysId, pKey, devtype, sn, meId, sVer, hVer, connType,
      mac, power, mode, dc = false, nvm.get("MqttHost"),
                             tonumber(nvm.get("MqttPort")),
                             nvm.get("MqttKeepAlive"), nvm.get("MqttLoginName"),
                             nvm.get("MqttLoginPwm"), nvm.get("MqttTransport"),
                             nvm.get("MqttConnectionTimeout"),
                             nvm.get("MqttCleanSession"),
                             nvm.get("MQTTVersion"), nvm.get("MqttQos"),
                             nvm.get("MqttRetain"), nvm.get("sysId"),
                             nvm.get("PKey"), nvm.get("Devtype"), nvm.get("Sn"),
                             nvm.get("MeId"), nvm.get("SVer"), nvm.get("HVer"),
                             nvm.get("ConnType"), nvm.get("Mac"),
                             nvm.get("Power"), nvm.get("Mode"), nvm.get("Dc")
--- MQTT连接是否处于激活状态
-- @return 激活状态返回true，非激活状态返回false
-- @usage mqttTask.isReady()
function isReady() return ready end

-- 启动MQTT客户端任务
function startMQTTClient(sn)
    sys.taskInit(function()
        local retryConnectCnt, retryStartDevCnt  = 0, 0
        -- 创建一个MQTT客户端
        while true do
            if not socket.isReady() then
                retryConnectCnt = 0
                -- 等待网络环境准备就绪，超时时间是5分钟
                sys.waitUntil("IP_READY_IND", 300000)
                log.info("retryStartDevCnt 加1")
                retryStartDevCnt = retryStartDevCnt + 1
            end
            if socket.isReady() then
                retryStartDevCnt = 0
                -- 阻塞执行MQTT CONNECT动作，直至成功
                -- 如果使用ssl连接，打开mqttClient:connect("lbsmqtt.airm2m.com",1884,"tcp_ssl",{caCert="ca.crt"})，根据自己的需求配置
                -- mqttClient:connect("lbsmqtt.airm2m.com",1884,"tcp_ssl",{caCert="ca.crt"})
                local ts, seq
                ts = os.time() .. "000" -- 系统时间
                local devInfoSendTopic, devInfo =
                    terminalSendTheme.equipmentInformationAssembly(ts)
                log.info("mqttHost", mqttHost, "mqttPort", mqttPort,
                         "mqttTransport ", mqttTransport)
                local mqttClient = mqtt.client(sn, 300, "admin", "public", nil,
                                               {
                    qos = 0,
                    retain = 0,
                    topic = devInfoSendTopic,
                    payload = devInfo
                }, mQTTVersion)
                if mqttClient:connect("emq.enn.cn", "1883", mqttTransport) then
                    retryConnectCnt = 0
                    ready = true
                    ts = os.time() .. "000" -- 系统时间
                    devInfoSendTopic, devInfo =
                        terminalSendTheme.equipmentInformationAssembly(ts)
                    log.info("devInfoSendTopic", devInfoSendTopic, "devInfo",
                             devInfo)
                    mqttClient:publish(devInfoSendTopic, devInfo, 0)
                    -- 订阅主题
                    if mqttClient:subscribe({
                        ["/cloud/single/" .. pKey .. "/" .. sn .. "/info"] = 0,
                        ["/cloud/single/" .. pKey .. "/" .. sn .. "/rtg"] = 0,
                        ["/cloud/single/" .. pKey .. "/" .. sn .. "/call"] = 0,
                        ["/cloud/single/" .. pKey .. "/" .. sn .. "/set"] = 0,
                        ["/cloud/single/" .. pKey .. "/" .. sn .. "/change"] = 0
                    }) then
                        -- 循环处理接收和发送的数据
                        while true do
                            if not mqttInMsg.proc(mqttClient) then
                                log.error("mqttTask.mqttInMsg.proc error")
                                break
                            end
                            if not mqttOutMsg.procUser(mqttClient) then
                                log.error("mqttTask.mqttOutMsg proc error")
                                break
                            end
                        end
                    end
                    ready = false
                else
                    retryConnectCnt = retryConnectCnt + 1
                end
                -- 断开MQTT连接
                mqttClient:disconnect()
                if retryConnectCnt >= 5 then
                    link.shut()
                    retryConnectCnt = 0
                end
                sys.wait(500)
            else
                -- 进入飞行模式，20秒之后，退出飞行模式
                net.switchFly(true)
                sys.wait(20000)
                net.switchFly(false)
            end
            if retryStartDevCnt >= 7 then
                retryStartDevCnt = 0
                sys.restart("重启设备！")
            end
        end
    end)
end
